// 测试流程
//     1.再申请两个用户信息:小猪佩奇,小猪乔治,并且设置他们的头像
//     2.申请好友:猪爸爸申请猪妈妈好友,小猪佩奇申请猪妈妈好友,小猪乔治申请猪妈妈好友
//     3.获取好友申请列表:猪妈妈应该能获取到3个申请信息
//     4.处理好友申请:同意猪爸爸,同意小猪乔治,拒绝小猪佩奇
//     5.猪妈妈进行用户搜索:应该能搜索到小猪佩奇
//     6.猪妈妈获取好友列表:应该能搜索到猪爸爸和小猪乔治
//     7.猪妈妈删除小猪乔治好友
//     8.猪爸爸发起群聊:猪爸爸,猪妈妈,小猪佩奇,小猪乔治
//     9.猪爸爸给猪妈妈发送一条消息;给群聊发送消息
//     10.猪妈妈获取聊天会话列表
//     11.获取群聊成员
#include<gtest/gtest.h>
#include<gflags/gflags.h>
#include"etcd.hpp"
#include"channel.hpp"
#include"utils.hpp"
#include<thread>
#include"friend.pb.h"
#include"user.pb.h"
#include"message.pb.h"
#include"base.pb.h"

DEFINE_bool(run_mode,false,"程序运行的模式,false-调试,true-发布");
DEFINE_string(log_file,"","发布模式下,用于指定日志输出的文件");
DEFINE_int32(log_level,0,"发布模式下,用于指定日志输出等级");

DEFINE_string(etcd_host,"http://127.0.0.1:2379","服务注册中心地址");
DEFINE_string(base_service,"/service","服务监控根目录");
DEFINE_string(friend_service, "/service/friend_service", "服务监控根目录");

ServiceManager::ptr sm;

void apply_test(const std::string& uid1,const std::string& uid2)
{

    //3.通过RPC信道管理对象,获取提供Echo服务的信道
    auto channel = sm->choose(FLAGS_friend_service);
    if(!channel)
    {
        LOG_ERROR("获取通信信道失败");
        return ;
    }
    wzl::FriendService_Stub stub(channel.get());
    wzl::FriendAddReq req;
    wzl::FriendAddRsp rsp;
    req.set_request_id(wzl::uuid());
    req.set_user_id(uid1);
    req.set_respondent_id(uid2);
    brpc::Controller cntl;
    stub.FriendAdd(&cntl,&req,&rsp,nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
}

void get_apply_list(const std::string& uid1)
{

    //3.通过RPC信道管理对象,获取提供Echo服务的信道
    auto channel = sm->choose(FLAGS_friend_service);
    if(!channel)
    {
        LOG_ERROR("获取通信信道失败");
        return ;
    }
    wzl::FriendService_Stub stub(channel.get());
    wzl::GetPendingFriendEventListReq req;
    wzl::GetPendingFriendEventListRsp rsp;
    req.set_request_id(wzl::uuid());
    req.set_user_id(uid1);
    brpc::Controller cntl;
    stub.GetPendingFriendEventList(&cntl,&req,&rsp,nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
    for(int i =  0; i < rsp.event_size(); i++)
    {
        std::cout<<"-------------------------"<<std::endl;
        std::cout<<rsp.event(i).sender().user_id()<<std::endl;
        std::cout<<rsp.event(i).sender().nickname()<<std::endl;
        std::cout<<rsp.event(i).sender().avatar()<<std::endl;
    }
}

void process_apply_test(const std::string& uid1,bool agree,const std::string& apply_user_id)
{

    //3.通过RPC信道管理对象,获取提供Echo服务的信道
    auto channel = sm->choose(FLAGS_friend_service);
    if(!channel)
    {
        LOG_ERROR("获取通信信道失败");
        return ;
    }
    wzl::FriendService_Stub stub(channel.get());
    wzl::FriendAddProcessReq req;
    wzl::FriendAddProcessRsp rsp;
    req.set_request_id(wzl::uuid());
    req.set_user_id(uid1);
    req.set_agree(agree);
    req.set_apply_user_id(apply_user_id);
    brpc::Controller cntl;
    stub.FriendAddProcess(&cntl,&req,&rsp,nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
}

void search_test(const std::string& uid1,const std::string& key)
{

    //3.通过RPC信道管理对象,获取提供Echo服务的信道
    auto channel = sm->choose(FLAGS_friend_service);
    if(!channel)
    {
        LOG_ERROR("获取通信信道失败");
        return ;
    }
    wzl::FriendService_Stub stub(channel.get());
    wzl::FriendSearchReq req;
    wzl::FriendSearchRsp rsp;
    req.set_request_id(wzl::uuid());
    req.set_user_id(uid1);
    req.set_search_key(key);
    brpc::Controller cntl;
    stub.FriendSearch(&cntl,&req,&rsp,nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
    for(int i = 0; i<rsp.user_info_size();i++)
    {
        std::cout<<" -------------------"<<std::endl;
        std::cout<<rsp.mutable_user_info(i)->user_id()<<std::endl;
        std::cout<<rsp.mutable_user_info(i)->nickname()<<std::endl;
        std::cout<<rsp.mutable_user_info(i)->avatar()<<std::endl;
    }
}


void friend_list_test(const std::string& uid1)
{

    //3.通过RPC信道管理对象,获取提供Echo服务的信道
    auto channel = sm->choose(FLAGS_friend_service);
    if(!channel)
    {
        LOG_ERROR("获取通信信道失败");
        return ;
    }
    wzl::FriendService_Stub stub(channel.get());
    wzl::GetFriendListReq req;
    wzl::GetFriendListRsp rsp;
    req.set_request_id(wzl::uuid());
    req.set_user_id(uid1);
    brpc::Controller cntl;
    stub.GetFriendList(&cntl,&req,&rsp,nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
    for(int i = 0; i < rsp.friend_list_size();i++)
    {
        std::cout<<" -------------------"<<std::endl;
        std::cout<<rsp.mutable_friend_list(i)->user_id()<<std::endl;
        std::cout<<rsp.mutable_friend_list(i)->nickname()<<std::endl;
        std::cout<<rsp.mutable_friend_list(i)->avatar()<<std::endl;
    }
}

void remove_test(const std::string& uid1,const std::string& pid1)
{

    //3.通过RPC信道管理对象,获取提供Echo服务的信道
    auto channel = sm->choose(FLAGS_friend_service);
    if(!channel)
    {
        LOG_ERROR("获取通信信道失败");
        return ;
    }
    wzl::FriendService_Stub stub(channel.get());
    wzl::FriendRemoveReq req;
    wzl::FriendRemoveRsp rsp;
    req.set_request_id(wzl::uuid());
    req.set_user_id(uid1);
    req.set_peer_id(pid1);
    brpc::Controller cntl;
    stub.FriendRemove(&cntl,&req,&rsp,nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
}


void create_css_test(const std::string& uid1,const std::vector<std::string>& uid_list)
{

    //3.通过RPC信道管理对象,获取提供Echo服务的信道
    auto channel = sm->choose(FLAGS_friend_service);
    if(!channel)
    {
        LOG_ERROR("获取通信信道失败");
        return ;
    }
    wzl::FriendService_Stub stub(channel.get());
    wzl::ChatSessionCreateReq req;
    wzl::ChatSessionCreateRsp rsp;
    req.set_request_id(wzl::uuid());
    req.set_user_id(uid1);
    req.set_chat_session_name("我们三");
    for(auto& id : uid_list)
    {
        req.add_member_id_list(id);
    }
    brpc::Controller cntl;
    stub.ChatSessionCreate(&cntl,&req,&rsp,nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
    std::cout<<rsp.chat_session_info().chat_session_id()<<std::endl;
    std::cout<<rsp.chat_session_info().chat_session_name()<<std::endl;
}

void css_member_test(const std::string& uid1,const std::string& cssid)
{

    //3.通过RPC信道管理对象,获取提供Echo服务的信道
    auto channel = sm->choose(FLAGS_friend_service);
    if(!channel)
    {
        LOG_ERROR("获取通信信道失败");
        return ;
    }
    wzl::FriendService_Stub stub(channel.get());
    wzl::GetChatSessionMemberReq req;
    wzl::GetChatSessionMemberRsp rsp;
    req.set_request_id(wzl::uuid());
    req.set_user_id(uid1);
    req.set_chat_session_id(cssid);
    brpc::Controller cntl;
    stub.GetChatSessionMember(&cntl,&req,&rsp,nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
    for(int i = 0; i < rsp.member_info_list_size();i++)
    {
        std::cout<<" -------------------"<<std::endl;
        std::cout<<rsp.mutable_member_info_list(i)->user_id()<<std::endl;
        std::cout<<rsp.mutable_member_info_list(i)->nickname()<<std::endl;
        std::cout<<rsp.mutable_member_info_list(i)->avatar()<<std::endl;
    }
}

void css_list_test(const std::string& uid1)
{

    //3.通过RPC信道管理对象,获取提供Echo服务的信道
    auto channel = sm->choose(FLAGS_friend_service);
    if(!channel)
    {
        LOG_ERROR("获取通信信道失败");
        return ;
    }
    wzl::FriendService_Stub stub(channel.get());
    wzl::GetChatSessionListReq req;
    wzl::GetChatSessionListRsp rsp;
    req.set_request_id(wzl::uuid());
    req.set_user_id(uid1);
    brpc::Controller cntl;
    stub.GetChatSessionList(&cntl,&req,&rsp,nullptr);
    ASSERT_FALSE(cntl.Failed());
    ASSERT_TRUE(rsp.success());
    for(int i = 0; i < rsp.chat_session_info_list_size();i++)
    {
        std::cout<<" -------------------"<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->single_chat_friend_id()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->chat_session_id()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->chat_session_name()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->avatar()<<std::endl;
        std::cout<<"消息内容"<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->prev_message().message_id()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->prev_message().chat_session_id()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->prev_message().timestamp()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->prev_message().sender().nickname()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->prev_message().sender().avatar()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->prev_message().sender().user_id()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->prev_message().message().file_message().file_name()<<std::endl;
        std::cout<<rsp.mutable_chat_session_info_list(i)->prev_message().message().file_message().file_contents()<<std::endl;
    }
}


int main(int argc,char* argv[])
{
    testing::InitGoogleTest(&argc,argv);
    google::ParseCommandLineFlags(&argc,&argv,true);
    wzl::init_logger(FLAGS_run_mode,FLAGS_log_file,FLAGS_log_level);

    //1. 先构造Rpc信道管理对象
    sm = std::make_shared<ServiceManager>();
    sm->declared(FLAGS_friend_service);
    auto put_cb = std::bind(&ServiceManager::onServiceOnline, sm.get(), std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&ServiceManager::onServiceOffline, sm.get(), std::placeholders::_1, std::placeholders::_2);
    // //2. 构造服务发现对象
    Discovery::ptr dclient = std::make_shared<Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);
    
    // apply_test("d303-acc6df72-0001","7134-17594d97-0000");
    // apply_test("06cd-8fd9c09c-0002","7134-17594d97-0000");
    // apply_test("9ab0-c595e6ce-0003","7134-17594d97-0000");

    //get_apply_list("7134-17594d97-0000");

    // process_apply_test("7134-17594d97-0000",true,"d303-acc6df72-0001");
    // process_apply_test("7134-17594d97-0000",false,"06cd-8fd9c09c-0002");
    // process_apply_test("7134-17594d97-0000",true,"9ab0-c595e6ce-0003");

    // search_test("7134-17594d97-0000","猪");
    // search_test("d303-acc6df72-0001","猪");
    // search_test("06cd-8fd9c09c-0002","乔治");

    // friend_list_test("7134-17594d97-0000");
    // friend_list_test("d303-acc6df72-0001");
    // friend_list_test("9ab0-c595e6ce-0003");
    // friend_list_test("06cd-8fd9c09c-0002");

    //remove_test("7134-17594d97-0000","9ab0-c595e6ce-0003");

    // std::vector<std::string> uid_list = {"d303-acc6df72-0001","7134-17594d97-0000","06cd-8fd9c09c-0002","9ab0-c595e6ce-0003"};
    // create_css_test("d303-acc6df72-0001",uid_list);

    // css_member_test("7134-17594d97-0000","9aef-0f829d2f-0000");
    // std::cout<<"========================================================="<<std::endl;
    // css_member_test("d303-acc6df72-0001","9aef-0f829d2f-0000");

    css_list_test("7134-17594d97-0000");

    return 0;
}